package edu.cs.usask.ca.silver.api.businesslogic;

import java.util.Date;

import edu.cs.usask.ca.silver.api.persistence.StorageI;
import edu.cs.usask.ca.silver.businesslogic.ids.FileID;
import edu.cs.usask.ca.silver.businesslogic.ids.ModelVersionID;
import edu.cs.usask.ca.silver.businesslogic.ids.ParameterID;
import edu.cs.usask.ca.silver.businesslogic.ids.ParameterSetID;
import edu.cs.usask.ca.silver.businesslogic.ids.ScenarioCollectionID;
import edu.cs.usask.ca.silver.businesslogic.ids.ScenarioID;
import edu.cs.usask.ca.silver.definitions.SupportedModelType;

/**
 * 
 * Interface specification for the Scenario bean
 * 
 * @author Daniel Funk, Yudi Xue
 * 
 */
public interface ScenarioI {

	/**
	 * Creates a new scenario in the storage layer.
	 * 
	 * TODO - this should create it's own parameterSet rather than requiring
	 * that a parameterSetID be passed in.
	 * 
	 * @param sName
	 *            The scenario name
	 * @param sCreator
	 *            Scenario creator
	 * @param sDescr
	 *            Scenario description
	 * @param mvId
	 *            The model version this scenario belongs to
	 * @param scId
	 *            The scenario collection this scenario belongs to
	 * @param psId
	 *            The parameter set contained within this scenario
	 * @param storage TODO
	 * @return A unique ScenarioID
	 */
	public ScenarioID createGenericScenario(String sName, String sCreator,
			String sDescr, ModelVersionID mvId, ScenarioCollectionID scId,
			ParameterSetID psId, StorageI storage) throws Exception;

	/**
	 * Creates a scenario in the storage layer and automatically adds it's own
	 * parameter set.
	 * 
	 * @param sName
	 *            The scenario name
	 * @param sCreator
	 *            Scenario creator
	 * @param sDescr
	 *            Scenario description
	 * @param mvId
	 *            The model version this scenario belongs to
	 * @param scId
	 *            The scenario collection this scenario belongs to
	 * @param storage TODO
	 * @return A unique ScenarioID
	 */
	public ScenarioID createGenericScenarioAndParameterSet(String sName,
			String sCreator, String sDescr, ModelVersionID mvId,
			ScenarioCollectionID scId, StorageI storage) throws Exception;

	/**
	 * Returns a string containing the XML representation (non-recursive) of a
	 * scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return String containing the XML representation of a scenario
	 */
	public String getScenarioAsXML(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the name of a scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return The scenario name
	 */
	public String getName(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the description of a scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Scenario description
	 */
	public String getDescription(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the creator of a scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Scenario creator
	 */
	public String getCreator(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the type of a scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Scenario type
	 */
	public String getType(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the creation date of a scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Scenario creation date
	 */
	public Date getCreationDate(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the creation time of a scenario
	 * 
	 * @param sId
	 *            A unique Scenario ID
	 * @param storage TODO
	 * @return Scenario creation time
	 */
	public Date getCreationTime(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns an array of FileIDs of all files associated with this scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Array of fileIDs of all file associated with this collection
	 * @throws Exception
	 */
	public FileID[] getAssociatedFileIds(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the ModelVersionID of the parent version of a scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return The ID of the parent ModelVersion
	 */
	public ModelVersionID getParentVersionId(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the type of the parent ModelVersion for this scenario.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return the Type of parent model version
	 * @throws NullPointerException
	 */
	public String getParentVersionSimulationType(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the ScenarioCollectionID of the scenario collection this scenario
	 * belongs to
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return ScenarioCollectionID of the parent collection
	 */
	public ScenarioCollectionID getScenarioCollectionId(ScenarioID sId, StorageI storage)
			throws Exception;

	/**
	 * Returns the name of the user who last ran the scenario simulation
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return User name who ran the scenario last
	 */
	public String getScenarioRunUser(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the start time of the last scenario simulation execution
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Start time of the last scenario simulation execution
	 */
	public Date getScenarioRunStartTime(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the end time of the last scenario simulation execution
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return End time of the last scenario simulation execution
	 */
	public Date getScenarioRunEndTime(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns an array of ParameterIDs, of all the parameters that belong to
	 * this scenario.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Array of ParameterIDs
	 */
	public ParameterID[] getParameterIds(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the ParameterSetID associated with current scenario.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * 
	 * @return The parameter set id associated with current scenario.
	 */
	public ParameterSetID getParameterSetId(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns an array of FileIDs of all input files for this scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Array of input FileIDs
	 */
	public FileID[] getInputFileIds(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the FileID of the only input files for this scenario; only use it
	 * if the model version has one input file.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return the input file id
	 * @throws NullPointerException
	 */
	public FileID getOneInputFileId(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the name of the only input file for this scenario; only use it if
	 * the hmodel version has one input file.
	 * 
	 * @param sId
	 *            A uique ScenarioID
	 * @param storage TODO
	 * @return the input file name
	 * @throws NullPointerException
	 */
	public String getOneInputFileName(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns an array of FileIDs of all trajectory files for this scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Array of trajectory FileIDs
	 */
	public FileID[] getTrajectoryFileIds(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns an array of FileIDs of all analysis files for this scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return Array of analysis FileIDs
	 */
	public FileID[] getAnalysisFileIds(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Update the name of a scenario in the storage layer
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param name
	 *            The (new) scenario name
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setName(ScenarioID sId, String name, StorageI storage) throws Exception;

	/**
	 * Update/set the type of a scenario in the storage layer
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param type
	 *            The (new) scenario type
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setType(ScenarioID sId, SupportedModelType type, StorageI storage)
			throws Exception;

	/**
	 * Update the description of a scenario in the storage layer
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param description
	 *            The (new) description of a scenario
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setDescription(ScenarioID sId, String description, StorageI storage)
			throws Exception;

	/**
	 * Update the collectionID of the collection this scenario belongs to
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param scId
	 *            The (new) ScenarioCollectionID
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setScenarioCollectionId(ScenarioID sId,
			ScenarioCollectionID scId, StorageI storage) throws Exception;

	/**
	 * Update the user name for the current scenario simulation execution
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param user
	 *            The user name
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setScenarioRunUser(ScenarioID sId, String user, StorageI storage)
			throws Exception;

	/**
	 * Set the start time for the current scenario simulation run. Sets the
	 * start time to the current time.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setScenarioRunStartTime(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Set the end time for the current scenario simulation run. Sets the end
	 * time to the current time.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean setScenarioRunEndTime(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Removes a scenario from the storage layer.
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param storage TODO
	 * @return TODO
	 */
	public boolean deleteScenario(ScenarioID sId, StorageI storage) throws Exception;

	/**
	 * Returns the value of a parameter in a specific scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param pId
	 *            A unique ParameterID
	 * @param storage TODO
	 * @return The value of this parameter in the given scenario
	 */
	public String getParameterValue(ScenarioID sId, ParameterID pId, StorageI storage)
			throws Exception;

	/**
	 * Returns the value comment of a parameter in a specific scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param pId
	 *            A unique ParameterID
	 * @param storage TODO
	 * @return The comment regarding the chosen value of a parameter in a
	 *         scenario
	 */
	public String getParameterComment(ScenarioID sId, ParameterID pId, StorageI storage)
			throws Exception;

	/**
	 * Update the value comment for a parameter in a specific scenario
	 * 
	 * @param sId
	 *            A unique ScenarioID
	 * @param pId
	 *            A unique ParameterID
	 * @param comment
	 *            The (new) value comment for a parameter in a specific scenario
	 * @param storage TODO
	 */
	public void setParameterComment(ScenarioID sId, ParameterID pId,
			String comment, StorageI storage) throws Exception;

	/**
	 * Check whether the current scenario is a baseline scenario
	 * 
	 * @param sId
	 * @param storage TODO
	 * @return
	 * 
	 */
	public boolean isBaseLineScenario(ScenarioID sId, StorageI storage) throws Exception;

	public ScenarioID createVensimScenario(String sName, String sCreator,
			String sDescr, ModelVersionID mvId, ScenarioCollectionID scId,
			ParameterSetID psId, StorageI storage) throws Exception;

	public ScenarioID createVensimScenarioAndParameterSet(String sName,
			String sCreator, String sDescr, ModelVersionID mvId,
			ScenarioCollectionID scId, StorageI storage) throws Exception;

	public boolean setScenarioAsBaselineToParentModelVersion(ScenarioID sId,
			StorageI storage) throws Exception;

	public ScenarioID duplicateScenario(ScenarioID sId, ScenarioCollectionID scId,
			StorageI storage) throws Exception;

}